package br.com.java3deditor.main;

import java.io.File;
import java.io.FileWriter;
import java.util.List;

import javax.media.j3d.Appearance;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix3d;
import javax.vecmath.Vector3d;

import br.com.java3deditor.primitives.VBox;
import br.com.java3deditor.primitives.VCone;
import br.com.java3deditor.primitives.VCylinder;
import br.com.java3deditor.primitives.VSphere;

/**
 * Class that has methods to generate all the code from the scene.
 * 
 * @author		Márcio de Souza Júnior
 * @version     1.0.0
 */

public class GenerateScript {
	
	private JFileChooser fc = new JFileChooser();
	
	// The name that will be used for the class and file to be saved
	private String className = "";
	
	// All generated code is written to that variable, to later saved to a file
	private String code =	
		"/******************************************************\n" +
		"* Code automatically generated by Java3DEditor 1.0.0  *\n" +
		"* Developer: Márcio de Souza Júnior                   *\n" +
		"* Email/MSN: marciosouzajunior@gmail.com              *\n" +
		"* Site: java3deditor.com                              *\n" +		
		"* Version of Java 3D: 1.5.1                           *\n" + 
		"*******************************************************/\n\n";
	
	
	/**
	 * Returns the class name that is used to generate and save the script file.
	 * Used to check if the user canceled saving the file.
	 * @return String
	 */
	public String getClassName() {
		return className;
	}

	
	/**
	 * This method receives an array containing all
	 * the objects in the scene. It traverses the 
	 * array by checking the type of the object 
	 * (VBox, VCone or VCylinder VSphere). Each type
	 * of object found, their characteristics are 
	 * returned and generates code that can be used
	 * to create the same objects.
	 * 
	 * @param objects	Array containing all the objects in the scene
	 */
	
	public void generateCode(List<Object> objects){
		
		int index = 0;
			
		// To get TransformGroup
		TransformGroup trg = new TransformGroup();
		Transform3D trf = new Transform3D();
		
		// To get color attributes
		Appearance ap = new Appearance();
		Color3f cor = new Color3f(0.0f,0.0f,0.0f);
		
		// To get transformations
		Vector3d position = new Vector3d();
		Vector3d scale = new Vector3d();
		Matrix3d rotation = new Matrix3d();
		
		
		while (index < objects.size())
		{
			
			if (objects.get(index) instanceof VBox){
				
				// Get TransformGroup
				trg = (TransformGroup)((VBox)(objects.get(index))).getParent();
				
				// Put TransformGroup on Transform3D
				trg.getTransform(trf);					
				
				// Get transformations
				trf.get(position);
				trf.getScale(scale);
				trf.getRotationScale(rotation);
				
				// Get appearance				
				ap = ((VBox)(objects.get(index))).getAppearance();
				ap.getColoringAttributes().getColor(cor);
				
				this.code +=
					"		//\n" +
					"		// Object: " + ((VBox)(objects.get(index))).getName() + index + "\n" +
					"		//\n\n" +
					"		// TransformGroup\n " +
					"		TransformGroup trg" + ((VBox)(objects.get(index))).getName() + index + " = new TransformGroup();\n" + 
					"		trg" + ((VBox)(objects.get(index))).getName() + index + ".setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);\n\n" +
					
					"		// Appearance\n" +
					"		Color3f cor" + ((VBox)(objects.get(index))).getName() + index + " = new Color3f(" + cor.getX() + "f, " + cor.getY() + "f, " + cor.getZ() + "f);\n" + 
					"		ColoringAttributes colorAttributes" + ((VBox)(objects.get(index))).getName() + index + " = new ColoringAttributes();\n" +	
					"		colorAttributes" + ((VBox)(objects.get(index))).getName() + index + ".setColor(cor" + ((VBox)(objects.get(index))).getName() + index + ");\n" + 
					"		Appearance appearance" + ((VBox)(objects.get(index))).getName() + index + " = new Appearance();\n"+ 
					"		appearance" + ((VBox)(objects.get(index))).getName() + index + ".setColoringAttributes(colorAttributes" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Declaration\n" +
					"		Box " + ((VBox)(objects.get(index))).getName() + index + " = new Box(" + ((VBox)(objects.get(index))).getXdimension() +	"f, " + ((VBox)(objects.get(index))).getYdimension() + "f," + ((VBox)(objects.get(index))).getZdimension() + "f, Box.GENERATE_TEXTURE_COORDS, appearance" + ((VBox)(objects.get(index))).getName() + index + ");\n" +
					"		trg" + ((VBox)(objects.get(index))).getName() + index + ".addChild(" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" + 
					
					"		// Position\n" +
					"		Vector3d v3DPosition" + ((VBox)(objects.get(index))).getName() + index + " = new Vector3d(" + position.getX() + ", " + position.getY() + ", " + position.getZ()+");\n" + 
					"		Transform3D trfPosition" + ((VBox)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfPosition" + ((VBox)(objects.get(index))).getName() + index + ".set(v3DPosition" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Scale\n" +
					"		Vector3d v3DScale" + ((VBox)(objects.get(index))).getName() + index + " = new Vector3d(" + scale.getX() + ", " + scale.getY() + ", " + scale.getZ()+");\n" + 
					"		Transform3D trfScale" + ((VBox)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfScale" + ((VBox)(objects.get(index))).getName() + index + ".setScale(v3DScale" + ((VBox)(objects.get(index))).getName() + index + ");\n" +
					"		trfScale" + ((VBox)(objects.get(index))).getName() + index + ".mul(trfPosition" + ((VBox)(objects.get(index))).getName() + index + "); // Accumulating\n" +
					"		trg" + ((VBox)(objects.get(index))).getName() + index + ".setTransform(trfScale" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" +					
					
					"		// Rotation\n" +
					"		Matrix3d m3DRotation" + ((VBox)(objects.get(index))).getName() + index + " = new Matrix3d(" + 
																		rotation.getM00() + ", " + rotation.getM01() + ", " + rotation.getM02() + ",\n" +
					"												" + rotation.getM10() + ", " + rotation.getM11() + ", " + rotation.getM12() + ",\n" +
					"												" + rotation.getM20() + ", " + rotation.getM21() + ", " + rotation.getM22() + ");\n" +
					"		trfPosition" + ((VBox)(objects.get(index))).getName() + index + ".setRotation(m3DRotation" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Apply the transforms\n" +
					"		trg" + ((VBox)(objects.get(index))).getName() + index + ".setTransform(trfPosition" + ((VBox)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Add to BranchGroup\n" +
					"		brg.addChild(trg" + ((VBox)(objects.get(index))).getName() + index + ");\n\n\n";
			
			} else if (objects.get(index) instanceof VCone){
					
				// Get TransformGroup
				trg = (TransformGroup)((VCone)(objects.get(index))).getParent();
				
				// Put TransformGroup on Transform3D
				trg.getTransform(trf);					
				
				// Get transformations
				trf.get(position);
				trf.getScale(scale);
				trf.getRotationScale(rotation);
				
				// Get appearance				
				ap = ((VCone)(objects.get(index))).getAppearance();
				ap.getColoringAttributes().getColor(cor);
				
				this.code +=
					"		//\n" +					
					"		// Object: " + ((VCone)(objects.get(index))).getName() + index + "\n" +
					"		//\n\n" +					
					"		// TransformGroup\n " +
					"		TransformGroup trg" + ((VCone)(objects.get(index))).getName() + index + " = new TransformGroup();\n" + 
					"		trg" + ((VCone)(objects.get(index))).getName() + index + ".setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);\n\n" +
					
					"		// Appearance\n" +
					"		Color3f cor" + ((VCone)(objects.get(index))).getName() + index + " = new Color3f(" + cor.getX() + "f, " + cor.getY() + "f, " + cor.getZ() + "f);\n" + 
					"		ColoringAttributes colorAttributes" + ((VCone)(objects.get(index))).getName() + index + " = new ColoringAttributes();\n" +	
					"		colorAttributes" + ((VCone)(objects.get(index))).getName() + index + ".setColor(cor" + ((VCone)(objects.get(index))).getName() + index + ");\n" + 
					"		Appearance appearance" + ((VCone)(objects.get(index))).getName() + index + " = new Appearance();\n"+ 
					"		appearance" + ((VCone)(objects.get(index))).getName() + index + ".setColoringAttributes(colorAttributes" + ((VCone)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Declaration\n" +
					"		Cone " + ((VCone)(objects.get(index))).getName() + index + " = new Cone(" + ((VCone)(objects.get(index))).getRadius() +	"f, " + ((VCone)(objects.get(index))).getHeight() +	"f, Cone.GENERATE_TEXTURE_COORDS, appearance" + ((VCone)(objects.get(index))).getName() + index + ");\n" +
					"		trg" + ((VCone)(objects.get(index))).getName() + index + ".addChild(" + ((VCone)(objects.get(index))).getName() + index + ");\n\n" + 
					
					"		// Position\n" +
					"		Vector3d v3DPosition" + ((VCone)(objects.get(index))).getName() + index + " = new Vector3d(" + position.getX() + ", " + position.getY() + ", " + position.getZ()+");\n" + 
					"		Transform3D trfPosition" + ((VCone)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfPosition" + ((VCone)(objects.get(index))).getName() + index + ".set(v3DPosition" + ((VCone)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Scale\n" +
					"		Vector3d v3DScale" + ((VCone)(objects.get(index))).getName() + index + " = new Vector3d(" + scale.getX() + ", " + scale.getY() + ", " + scale.getZ()+");\n" + 
					"		Transform3D trfScale" + ((VCone)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfScale" + ((VCone)(objects.get(index))).getName() + index + ".setScale(v3DScale" + ((VCone)(objects.get(index))).getName() + index + ");\n" +
					"		trfScale" + ((VCone)(objects.get(index))).getName() + index + ".mul(trfPosition" + ((VCone)(objects.get(index))).getName() + index + "); // Accumulating\n" +
					"		trg" + ((VCone)(objects.get(index))).getName() + index + ".setTransform(trfScale" + ((VCone)(objects.get(index))).getName() + index + ");\n\n" +					

					"		// Rotation\n" +
					"		Matrix3d m3DRotation" + ((VCone)(objects.get(index))).getName() + index + " = new Matrix3d(" +
																		rotation.getM00() + ", " + rotation.getM01() + ", " + rotation.getM02() + ",\n" +
					"												" + rotation.getM10() + ", " + rotation.getM11() + ", " + rotation.getM12() + ",\n" +
					"												" + rotation.getM20() + ", " + rotation.getM21() + ", " + rotation.getM22() + ");\n" +
					"		trfPosition" + ((VCone)(objects.get(index))).getName() + index + ".setRotation(m3DRotation" + ((VCone)(objects.get(index))).getName() + index + ");\n" +

					"		// Apply the transforms\n" +
					"		trg" + ((VCone)(objects.get(index))).getName() + index + ".setTransform(trfPosition" + ((VCone)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Add to BranchGroup\n" +
					"		brg.addChild(trg" + ((VCone)(objects.get(index))).getName() + index + ");\n\n\n";
						
				
			}else if (objects.get(index) instanceof VCylinder){
				
				// Get TransformGroup 
				trg = (TransformGroup)((VCylinder)(objects.get(index))).getParent();
				
				// Put TransformGroup on Transform3D
				trg.getTransform(trf);					
				
				// Get transformations
				trf.get(position);
				trf.getScale(scale);
				trf.getRotationScale(rotation);
				
				// Get appearance				
				ap = ((VCylinder)(objects.get(index))).getAppearance();
				ap.getColoringAttributes().getColor(cor);
				
				this.code +=
					"		//\n" +					
					"		// Object: " + ((VCylinder)(objects.get(index))).getName() + index + "\n" +
					"		//\n\n" +					
					"		// TransformGroup\n " +
					"		TransformGroup trg" + ((VCylinder)(objects.get(index))).getName() + index + " = new TransformGroup();\n" + 
					"		trg" + ((VCylinder)(objects.get(index))).getName() + index + ".setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);\n\n" +
					
					"		// Appearance\n" +
					"		Color3f cor" + ((VCylinder)(objects.get(index))).getName() + index + " = new Color3f(" + cor.getX() + "f, " + cor.getY() + "f, " + cor.getZ() + "f);\n" + 
					"		ColoringAttributes colorAttributes" + ((VCylinder)(objects.get(index))).getName() + index + " = new ColoringAttributes();\n" +	
					"		colorAttributes" + ((VCylinder)(objects.get(index))).getName() + index + ".setColor(cor" + ((VCylinder)(objects.get(index))).getName() + index + ");\n" + 
					"		Appearance appearance" + ((VCylinder)(objects.get(index))).getName() + index + " = new Appearance();\n"+ 
					"		appearance" + ((VCylinder)(objects.get(index))).getName() + index + ".setColoringAttributes(colorAttributes" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Declaration\n" +
					"		Cylinder " + ((VCylinder)(objects.get(index))).getName() + index + " = new Cylinder("+((VCylinder)(objects.get(index))).getRadius() + "f, " + ((VCylinder)(objects.get(index))).getHeight() + "f, Cylinder.GENERATE_TEXTURE_COORDS, appearance" + ((VCylinder)(objects.get(index))).getName() + index + ");\n" +
					"		trg" + ((VCylinder)(objects.get(index))).getName() + index + ".addChild(" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" + 
					
					"		// Position\n" +
					"		Vector3d v3DPosition" + ((VCylinder)(objects.get(index))).getName() + index + " = new Vector3d(" + position.getX() + ", " + position.getY() + ", " + position.getZ()+");\n" + 
					"		Transform3D trfPosition" + ((VCylinder)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfPosition" + ((VCylinder)(objects.get(index))).getName() + index + ".set(v3DPosition" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Scale\n" +
					"		Vector3d v3DScale" + ((VCylinder)(objects.get(index))).getName() + index + " = new Vector3d(" + scale.getX() + ", " + scale.getY() + ", " + scale.getZ()+");\n" + 
					"		Transform3D trfScale" + ((VCylinder)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfScale" + ((VCylinder)(objects.get(index))).getName() + index + ".setScale(v3DScale" + ((VCylinder)(objects.get(index))).getName() + index + ");\n" +
					"		trfScale" + ((VCylinder)(objects.get(index))).getName() + index + ".mul(trfPosition" + ((VCylinder)(objects.get(index))).getName() + index + "); // Accumulating\n" +
					"		trg" + ((VCylinder)(objects.get(index))).getName() + index + ".setTransform(trfScale" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" +					
					
					"		// Rotation\n" +
					"		Matrix3d m3DRotation" + ((VCylinder)(objects.get(index))).getName() + index + " = new Matrix3d(" +
																		rotation.getM00() + ", " + rotation.getM01() + ", " + rotation.getM02() + ",\n" +
					"												" + rotation.getM10() + ", " + rotation.getM11() + ", " + rotation.getM12() + ",\n" +
					"												" + rotation.getM20() + ", " + rotation.getM21() + ", " + rotation.getM22() + ");\n" +
					"		trfPosition" + ((VCylinder)(objects.get(index))).getName() + index + ".setRotation(m3DRotation" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Apply the transforms\n" +
					"		trg" + ((VCylinder)(objects.get(index))).getName() + index + ".setTransform(trfPosition" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Add to BranchGroup\n" +
					"		brg.addChild(trg" + ((VCylinder)(objects.get(index))).getName() + index + ");\n\n\n";
				
			}else if (objects.get(index) instanceof VSphere){
				
				// Get TransformGroup 
				trg = (TransformGroup)((VSphere)(objects.get(index))).getParent();
				
				// Put TransformGroup on Transform3D
				trg.getTransform(trf);					
				
				// Get transformations
				trf.get(position);
				trf.getScale(scale);
				trf.getRotationScale(rotation);
				
				// Get appearance				
				ap = ((VSphere)(objects.get(index))).getAppearance();
				ap.getColoringAttributes().getColor(cor);
				
				this.code +=
					"		//\n" +					
					"		// Object: " + ((VSphere)(objects.get(index))).getName() + index + "\n" +
					"		//\n\n" +					
					"		// TransformGroup\n " +
					"		TransformGroup trg" + ((VSphere)(objects.get(index))).getName() + index + " = new TransformGroup();\n" + 
					"		trg" + ((VSphere)(objects.get(index))).getName() + index + ".setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);\n\n" +
					
					"		// Appearance\n" +
					"		Color3f cor" + ((VSphere)(objects.get(index))).getName() + index + " = new Color3f(" + cor.getX() + "f, " + cor.getY() + "f, " + cor.getZ() + "f);\n" + 
					"		ColoringAttributes colorAttributes" + ((VSphere)(objects.get(index))).getName() + index + " = new ColoringAttributes();\n" +	
					"		colorAttributes" + ((VSphere)(objects.get(index))).getName() + index + ".setColor(cor" + ((VSphere)(objects.get(index))).getName() + index + ");\n" + 
					"		Appearance appearance" + ((VSphere)(objects.get(index))).getName() + index + " = new Appearance();\n"+ 
					"		appearance" + ((VSphere)(objects.get(index))).getName() + index + ".setColoringAttributes(colorAttributes" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Declaration\n" +
					"		Sphere " + ((VSphere)(objects.get(index))).getName() + index + " = new Sphere("+((VSphere)(objects.get(index))).getRadius() + "f, Sphere.GENERATE_TEXTURE_COORDS, appearance" + ((VSphere)(objects.get(index))).getName() + index + ");\n" +
					"		trg" + ((VSphere)(objects.get(index))).getName() + index + ".addChild(" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" + 
					
					"		// Position\n" +
					"		Vector3d v3DPosition" + ((VSphere)(objects.get(index))).getName() + index + " = new Vector3d(" + position.getX() + ", " + position.getY() + ", " + position.getZ()+");\n" + 
					"		Transform3D trfPosition" + ((VSphere)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfPosition" + ((VSphere)(objects.get(index))).getName() + index + ".set(v3DPosition" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Scale\n" +
					"		Vector3d v3DScale" + ((VSphere)(objects.get(index))).getName() + index + " = new Vector3d(" + scale.getX() + ","+ scale.getY() +","+ scale.getZ()+");\n" + 
					"		Transform3D trfScale" + ((VSphere)(objects.get(index))).getName() + index + " = new Transform3D();\n" +
					"		trfScale" + ((VSphere)(objects.get(index))).getName() + index + ".setScale(v3DScale" + ((VSphere)(objects.get(index))).getName() + index + ");\n" +
					"		trfScale" + ((VSphere)(objects.get(index))).getName() + index + ".mul(trfPosition" + ((VSphere)(objects.get(index))).getName() + index + "); // Accumulating\n" +
					"		trg" + ((VSphere)(objects.get(index))).getName() + index + ".setTransform(trfScale" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" +					
					
					"		// Rotation\n" +
					"		Matrix3d m3DRotation" + ((VSphere)(objects.get(index))).getName() + index + " = new Matrix3d(" +
																		rotation.getM00() + ", " + rotation.getM01() + ", " + rotation.getM02() + ",\n" +
					"												" + rotation.getM10() + ", " + rotation.getM11() + ", " + rotation.getM12() + ",\n" +
					"												" + rotation.getM20() + ", " + rotation.getM21() + ", " + rotation.getM22() + ");\n" +
					"		trfPosition" + ((VSphere)(objects.get(index))).getName() + index + ".setRotation(m3DRotation" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Apply the transforms\n" +
					"		trg" + ((VSphere)(objects.get(index))).getName() + index + ".setTransform(trfPosition" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n" +
					
					"		// Add to BranchGroup\n" +
					"		brg.addChild(trg" + ((VSphere)(objects.get(index))).getName() + index + ");\n\n\n";
			}
					
			index++;
				
		};
		
		this.generateFinalCode();
		this.save(this.code);
	}
	
	
	/**
	 * Save the generated code in a file .java
	 * 
	 * @param code	String containing all the generated code
	 */
	
	public void save(String code){  
		      
		try
		{
			File file = new File(fc.getCurrentDirectory() + "\\" + className + ".java");   
			
			if (file.exists())
			{	  
				int r = JOptionPane.showConfirmDialog(null, "File already exists, overwrite?", "Generate Script", JOptionPane.YES_NO_OPTION);
				
				if (r == 0)	
					file.delete(); 
				else
					return;								      
				
			}
			
			try
			{    
				FileWriter fw = new FileWriter(fc.getCurrentDirectory()+ "\\" + className + ".java", true);               
				fw.write(code);
				fw.close();   
				JOptionPane.showMessageDialog(null, "Script generated successfully.", "Generate Script", JOptionPane.INFORMATION_MESSAGE);
				
			} catch(Exception e){   
				JOptionPane.showMessageDialog(null, e.getClass() + ": "
						+ e.getMessage(), "An error occurred", JOptionPane.ERROR_MESSAGE);
			}
		}catch(Exception ex){
			JOptionPane.showMessageDialog(null, ex.getClass() + ": "
					+ ex.getMessage(), "An error occurred", JOptionPane.ERROR_MESSAGE);
		}
	
	} 
	
	
	/**
	 * Create a start code used by all scenes.
	 */	
	public void generateInitialCode(){
		
		int returnVal = fc.showDialog(Main.getDesktop(), "Save");
		
		if (returnVal == JFileChooser.APPROVE_OPTION) 
		{
		        		    
			className = fc.getSelectedFile().getName();
		 
			this.code +=
				"import java.awt.GraphicsConfiguration;\n" +   
				"import javax.media.j3d.Appearance;\n" +   
				"import javax.media.j3d.Background;\n" +   
				"import javax.media.j3d.BoundingSphere;\n" +   
				"import javax.media.j3d.BranchGroup;\n" +   
				"import javax.media.j3d.Canvas3D;\n" +   
				"import javax.media.j3d.ColoringAttributes;\n" +   
				"import javax.media.j3d.Transform3D;\n" +   
				"import javax.media.j3d.TransformGroup;\n" +   
				"import javax.swing.JFrame;\n" +   
				"import javax.swing.WindowConstants;\n" +   
				"import javax.vecmath.Color3f;\n" +   
				"import javax.vecmath.Point3d;\n" +   
				"import javax.vecmath.Matrix3d;\n" +
				"import javax.vecmath.Vector3d;\n" +   
				"import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;\n" +  
				"import com.sun.j3d.utils.geometry.Sphere;\n"  +
				"import com.sun.j3d.utils.geometry.Box;\n" +   
				"import com.sun.j3d.utils.geometry.Cone;\n" +   
				"import com.sun.j3d.utils.geometry.Cylinder;\n" +   
				"import com.sun.j3d.utils.universe.SimpleUniverse;\n" + 
				"import com.sun.j3d.utils.universe.ViewingPlatform;\n\n" + 
				
				"public class " + className + " {\n\n" +
				"	// Constructor\n " +					
				"	public " + className + " () {\n\n " +
				"		// Default code of the scene\n " +						
				"		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();\n " + 
				"		Canvas3D scene = new Canvas3D(config);\n" + 
				"		BranchGroup brg = new BranchGroup ();\n\n" +
				"		/*****************************************\n" +
				"				    Object Declarations	          \n" +
				"		******************************************/\n\n";
				            
		}
			
	}
	
	
	/**
	 * Create a final code used by all scenes.
	 */	
	public void generateFinalCode(){
		
		this.code +=   
		"		/*****************************************\n" +
		"					     Final Declarations       \n" +
		"		******************************************/\n\n" + 
		
		"		// Background color\n" +
		"		Color3f bgColor= new Color3f(94,170,227);\n" + 
		"		Background bg = new Background(bgColor);\n" +
		"		bg.setApplicationBounds(new BoundingSphere());\n" +
		"		brg.addChild(bg);\n\n" +
		
		"		// Compile the scene and create the universe\n" +		
		"		brg.compile();\n" +
		"		SimpleUniverse universe = new SimpleUniverse (scene);\n" +
		"		universe.addBranchGraph(brg);\n" +
		"		universe.getViewingPlatform().setNominalViewingTransform();\n\n " +
		
		"		// Behavior for visualization\n" +		
		"		OrbitBehavior orbit = new OrbitBehavior();\n" +
		"		orbit.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0));\n" +
		"		ViewingPlatform view = universe.getViewingPlatform();\n" +
		"		view.setNominalViewingTransform();\n" +
		"		view.setViewPlatformBehavior(orbit);\n\n " +
		
		"		// Create the window\n" +					
		"		JFrame window = new JFrame (\"Java3DEditor\");\n" +
		"		window.setBounds(0,0,800,600);\n" +
		"		window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);\n" +
		"		window.add(scene);\n" +
		"		window.setVisible(true);\n" +
		"	}\n\n" +
		
		"	public static void main(String[] args) {\n" + 
		"		new " + className + "();\n" + 
		"	}\n" +
		"}";
			
	}
	/**
	 * Return the string with the first letter upper case and the rest lower case.
	 * 
	 * @param word	String to be converted
	 */
    @SuppressWarnings("unused")
	private static String fcase( final String word ) {
    	
        if( word != null ) {
            int len = word.length();
            String out = "";
            out += word.substring(0, 1).toUpperCase();
            out += word.substring(1, len).toLowerCase();
            return out;
        }
        return word;
    }	
		
}
